﻿using System.Windows.Controls;
using System.Windows;
using System;

namespace NavFx.NavFxDemo
{
	/// <summary>
	/// Application shell providing features that will remain the same throughout the application
	/// </summary>
	public partial class Shell: HostPage
	{
		#region Constructors

		/// <summary>
		/// Default constructor
		/// </summary>
		public Shell()
		{
			InitializeComponent();
		}

		#endregion

		#region Overrides

		/// <summary>
		/// Override to load new pages into the panel provided
		/// </summary>
		/// <param name="newContent">New page to be loaded</param>
		public override void SetContent(System.Windows.Controls.UserControl newContent)
		{
			this.contentPanel.Children.Clear();
			this.contentPanel.Children.Add(newContent);
		}

		#endregion

		#region Public members

		/// <summary>
		/// Writes a line of text to the Output pane
		/// </summary>
		/// <param name="output">Output to be written</param>
		internal void WriteOutput(string output)
		{
			TextBlock outputBlock = new TextBlock();
			outputBlock.Margin = new Thickness(2);
			outputBlock.FontSize = 12D;
			outputBlock.TextAlignment = TextAlignment.Left;
			outputBlock.Text = output;
			this.outputTextPanel.Children.Add(outputBlock);

			//TODO: get last block entered to scroll into view
			//if anyone knows how to do this let me know
		}

		#endregion

		#region Private members

		/// <summary>
		/// Helper method to populate the watch list of registered pages
		/// </summary>
		private void loadRegisteredPages()
		{
			//clear the list of registered pages
			//and re-populate, tried using binding
			//but got an exception, not concerned
			//about making it work with binding as
			//other than this demo can't see any real
			//scenarios where it would be needed
			this.registeredPages.Items.Clear();
			foreach(IPage page in this.Navigator)
			{
				this.registeredPages.Items.Add(page.Path);
			}

			//update the count of registered pages
			this.pageCount.Text = this.Navigator.PageCount.ToString();

			//write to output window
			Application.Current.WriteOutput("\nIn loadRegisteredPages of Shell.xaml.cs excuting...");
			Application.Current.WriteOutput("foreach(IPage page in this.Navigator)\n{\n\tthis.registeredPages.Items.Add(page.Path);\n}");
			Application.Current.WriteOutput("this.pageCount.Text = this.Navigator.PageCount.ToString();");
		}

		#endregion

		/// <summary>
		/// Initialise the shell on loading
		/// </summary>
		private void HostPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
		{
			//register and load the home page
			//into the content panel
			//relying on the fact that a default
			//transition handler has been set by
			//the application
			Home homePage = new Home();
			this.Navigator.RegisterPage(homePage);
			this.Navigator.GoToPage("Home");

			//write to output window
			Application.Current.WriteOutput("\nIn HostPage_Loaded of Shell.xaml.cs excuting...");
			Application.Current.WriteOutput("Home homePage = new Home();");
			Application.Current.WriteOutput("this.Navigator.RegisterPage(homePage);");
			Application.Current.WriteOutput("this.Navigator.GoToPage(\"Home\");");

			this.loadRegisteredPages();

			//wire up a handler to refresh registered pages list
			//after any asynchronous request
			this.Navigator.PageLoadCompleted += new EventHandler<PageLoadCompletedEventArgs>(Navigator_PageLoadCompleted);

		}

		/// <summary>
		/// Handles notification of load from external libraries request to refresh list of registered pages
		/// </summary>
		void Navigator_PageLoadCompleted(object sender, PageLoadCompletedEventArgs e)
		{
			this.loadRegisteredPages();
		}

		/// <summary>
		/// Loads the home page on click of the Home button
		/// </summary>
		private void home_Click(object sender, System.Windows.RoutedEventArgs e)
		{
			if(this.Navigator.CurrentPage == "Home")
			{
				//Home is already displayed do nothing
				return;
			}

			//write to output window
			Application.Current.WriteOutput("\nIn home_Click of Shell.xaml.cs excuting...");
			
			if(((bool)this.simpleTransitor.IsChecked))
			{
				//Make sure the Transitor target is set to the application
				//and display the home page
				this.Navigator.Transitor = new SimpleTransitor(Application.Current);
				Application.Current.WriteOutput("this.Navigator.Transitor = new SimpleTransitor(Application.Current);");
			}
			else
			{
				this.Navigator.Transitor = new FadeTransitor(this.contentPanel, TimeSpan.FromSeconds(2));
				Application.Current.WriteOutput("this.Navigator.Transitor = new FadeTransitor(this.contentPanel, TimeSpan.FromSeconds(2));");
			}

			this.Navigator.GoToPage("Home");
			Application.Current.WriteOutput("this.Navigator.GoToPage(\"Home\");");
			
			//update the list of registered pages
			//in the watch panel
			this.loadRegisteredPages();
		}

		/// <summary>
		/// Displays IsPinned state of a Page on selection in registered pages list
		/// </summary>
		private void registeredPages_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
		{
			if(this.registeredPages.SelectedIndex != -1)
			{
				//the index based override of the indexer
				//is being used here to get a reference to
				//the page selected in registered pages
				this.isPinned.IsChecked = this.Navigator[this.registeredPages.SelectedIndex].IsPinned;

				//write to output window
				Application.Current.WriteOutput("\nIn registeredPages_SelectionChanged of Shell.xaml.cs executing...");
				Application.Current.WriteOutput("this.isPinned.IsChecked = this.Navigator[this.registeredPages.SelectedIndex].IsPinned;");
			}
		}

		/// <summary>
		/// Displays a page from an external library
		/// </summary>
		/// <remarks>
		/// This method demonstrates the use of the GoToPage overload
		/// that accepts a Uri instance pointing to the dll containing
		/// the page to be loaded
		/// </remarks>
		private void external1_Click(object sender, RoutedEventArgs e)
		{
			//prepare the uri
			Uri demoPagesUri = new Uri(@"NavFx.NavFxDemo.Pages.dll", UriKind.Relative);
			Application.Current.WriteOutput("Uri demoPagesUri = new Uri(@\"NavFx.NavFxDemo.Pages.dll\", UriKind.Relative);");

			if(this.Navigator.CurrentPage == "PanelPage1")
			{
				//PanelPage1 is already displayed do nothing
				return;
			}

			//write to output window
			Application.Current.WriteOutput("\nIn external1_Click of Shell.xaml.cs excuting...");
			

			if(((bool)this.simpleTransitor.IsChecked))
			{
				//Make sure the Transitor target is set to the application
				//and display the home page
				this.Navigator.Transitor = new SimpleTransitor(Application.Current);
				Application.Current.WriteOutput("this.Navigator.Transitor = new SimpleTransitor(Application.Current);");
			}
			else
			{
				this.Navigator.Transitor = new FadeTransitor(this.contentPanel, TimeSpan.FromSeconds(2));
				Application.Current.WriteOutput("this.Navigator.Transitor = new FadeTransitor(this.contentPanel, TimeSpan.FromSeconds(2));");
			}

			//display the page
			this.Navigator.GoToPage("PanelPage1", false, demoPagesUri);
			Application.Current.WriteOutput("this.Navigator.GoToPage(\"PanelPage1\", false, demoPagesUri);");

			//update the list of registered pages
			//if this method is called after external2_Click
			//the event handler will not have handled this
			this.loadRegisteredPages();
		}

		/// <summary>
		/// Displays a page from an external library
		/// </summary>
		/// <remarks>
		/// This method demonstrates the use of the GoToPage overload
		/// that accepts a url string pointing to the dll containing
		/// the page to be loaded, the method constructs a relative
		/// Uri instance before performing the actual load
		/// </remarks>
		private void external2_Click(object sender, RoutedEventArgs e)
		{
			//prepare the uri
			Uri demoPagesUri = new Uri(@"NavFx.NavFxDemo.Pages.dll", UriKind.Relative);
			Application.Current.WriteOutput("Uri demoPagesUri = new Uri(@\"NavFx.NavFxDemo.Pages.dll\", UriKind.Relative);");

			if(this.Navigator.CurrentPage == "PanelPage2")
			{
				//PanelPage2 is already displayed do nothing
				return;
			}

			//write to output window
			Application.Current.WriteOutput("\nIn external2_Click of Shell.xaml.cs excuting...");


			if(((bool)this.simpleTransitor.IsChecked))
			{
				//Make sure the Transitor target is set to the application
				//and display the home page
				this.Navigator.Transitor = new SimpleTransitor(Application.Current);
				Application.Current.WriteOutput("this.Navigator.Transitor = new SimpleTransitor(Application.Current);");
			}
			else
			{
				this.Navigator.Transitor = new FadeTransitor(this.contentPanel, TimeSpan.FromSeconds(2));
				Application.Current.WriteOutput("this.Navigator.Transitor = new FadeTransitor(this.contentPanel, TimeSpan.FromSeconds(2));");
			}

			//display the page
			this.Navigator.GoToPage("PanelPage2", false, demoPagesUri);
			Application.Current.WriteOutput("this.Navigator.GoToPage(\"PanelPage2\", false, demoPagesUri);");

			//update the list of registered pages
			//if this method is called after external2_Click
			//the event handler will not have handled this
			this.loadRegisteredPages();
		}
	}
}
